<?php

final class SQLRepository {

    private $class;
    private $columns;

    public function __construct($class) {
        $this->class = $class;
    }

    public function addColumn($column) {
        $this->columns[] = $column;
    }

    public function load(SQLCriteria $criteria) {
        $sql = new SQLSelect();
        if (isset($this->columns)) {
            foreach ($this->columns as $column) {
                $sql->addColumn($column);
            }
        } else {
            $sql->addColumn('*');
        }
        $sql->setEntity($this->class);
        $sql->setCriteria($criteria);

        if ($conn = SQLTransaction::get()) {
            $result = $conn->query($sql->getInstruction());
            $results = array();
            if ($result->rowCount() > 0) {
                $modelName = $this->class . 'Model';
                while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
                    $modelObj = new $modelName();
                    $modelObj->fromArray($row);
                    $results[] = $modelObj;
                }
            }
            return $results;
        } else {
            throw new NonActiveSQLConnectionException();
        }
    }

    public function delete(TCriteria $criteria) {
        $sql = new Delete();
        $sql->setEntity($this->class);
        $sql->setCriteria($criteria);

        if ($conn = Transaction::get()) {
            return $conn->exec($sql->getInstruction());
        } else {
            throw new NonActiveSQLConnectionException();
        }
    }

    public function count(Criteria $criteria = null) {
        $sql = new Select();
        $sql->addColumn('count(*)');
        $sql->setEntity($this->class);
        $sql->setCriteria($criteria);

        if ($conn = Transaction::get()) {
            $result = $conn->query($sql->getInstruction());
            if ($result != false) {
                $row = $result->fetch(PDO::FETCH_NUM);
            }
            return $row[0];
        } else {
            throw new NonActiveSQLConnectionException();
        }
    }

}
